package export;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;

import org.apache.commons.io.FilenameUtils;

import ar.com.fdvs.dj.domain.builders.DynamicReportBuilder;

/**
 * Manage all export action in application include: CWS and OXYC.
 * 
 * 
 */
public class ExportManager {
    protected ExportManager() {
    }

    /**
     * Export one report in OXYC.
     * 
     * @param builder
     * @param dataSource
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    public static String exportOXYC(DynamicReportBuilder builder, JRDataSource dataSource, ExportRequest request)
            throws JRException, IOException {
        InputStream fileStream = export(builder, dataSource, request);
        return writeStreamToFileOXYC(fileStream, request);
    }

    /**
     * Export many reports in OXYC in one file.
     * 
     * @param builders
     * @param dataSources
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    public static String exportOXYC(List<DynamicReportBuilder> builders, List<JRDataSource> dataSources,
            ExportRequest request) throws JRException, IOException {
        InputStream fileStream = export(builders, dataSources, request);
        return writeStreamToFileOXYC(fileStream, request);
    }

    /**
     * Write input stream which was returned by exporter and write it to file.
     * 
     * @param fileStream
     * @param request
     * @return
     * @throws IOException
     *             Having problem with System IO.
     */
    private static final String writeStreamToFileOXYC(InputStream fileStream, ExportRequest request) 
            throws IOException {
        
        ExportFileWriter fileWriter = new ExportFileWriter();
        String filePath = FilenameUtils.concat(request.getBasePath(), request.getFileName());
        fileWriter.downloadExportFile(fileStream, filePath);
        return filePath;
    }

    /**
     * Export one report in CWS.
     * 
     * @param builder
     * @param dataSource
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    public static InputStream exportCWS(DynamicReportBuilder builder, JRDataSource dataSource, ExportRequest request)
            throws JRException, IOException {

        return export(builder, dataSource, request);
    }

    /**
     * Export many reports in CWS in one file.
     * 
     * @param builders
     * @param dataSources
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    public static InputStream exportCWS(List<DynamicReportBuilder> builders, List<JRDataSource> dataSources,
            ExportRequest request) throws JRException, IOException {
        return export(builders, dataSources, request);
    }

    /**
     * Call another export method to export file.
     * @param builder
     * @param dataSource
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    protected static InputStream export(DynamicReportBuilder builder, JRDataSource dataSource, ExportRequest request)
            throws JRException, IOException {

        return export(Arrays.asList(builder), Arrays.asList(dataSource), request);
    }

    /**
     * Call directly to exporter to export file.
     * @param builders
     * @param dataSources
     * @param request
     * @return
     * @throws JRException
     * @throws IOException
     */
    protected static InputStream export(List<DynamicReportBuilder> builders, List<JRDataSource> dataSources,
            ExportRequest request) throws JRException, IOException {
        AbstractExporter exporter = null;

        // create export depend on export type
        if (request.getType() == ExportType.XLS) {
            exporter = new ExcelXlsExporter();
        } else if (request.getType() == ExportType.XLSX) {
            exporter = new ExcelExporter();
        }

        if (exporter == null) {
            throw new IllegalArgumentException("Export type does not support! Please check your export request again!");
        }
        // configure before exporting data
        exporter.configExporter(request);

        return exporter.export(builders, dataSources, request);
    }
}
